home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
BBS Toolkit
/
BBS Toolkit.iso
/
maximus
/
valmsg19.zip
/
VALMSG.C
next >
Wrap
C/C++ Source or Header
|
1992-08-26
|
12KB
|
365 lines
/*
VALMSG -- Creates validation messages from questionnaire data
Version 1.9 (8/26/92)
Written by Bob Quinlan of Austin, Texas, USA
Sysop of Red October at 512-834-2593 (1:382/111)
Copyright 1992 by Bob Quinlan
Compatible with Maximus 2.00 and 2.01
This program reads a single user's questionnaire data and generates a
message from that user to the sysop containing the data. You can change
the defaults for who the message comes from, who the messages is
addressed to, and what subject goes on the message.
/Mmessagearea Message area "number". This must be supplied.
/Vfile Validation file. This must be supplied.
/Aareafile Area file. Default is AREA.DAT in the current
directory.
/Fusername From username. If this is not supplied the first
line of the validation file will be assumed to be a
[post] entry and the user's name will be extracted
from it.
/Ssubject Subject line. (default: Questionnaire)
/Tusername To username. (default: Sysop)
You may want to supply multiple word values for /F, /S, and /T. You can
separate the words by spaces or by underscores (which will be replaced
by spaces). For example, both of these would produce the same results:
valmsg /mper /vquest.tmp /tBob Quinlan /sHello there!
valmsg /mper /vquest.tmp /tBob_Quinlan /sHello_there!
There are any number of ways that VALMSG can be used. I'll show you my
questionnaire and part of my Maximus batch file as examples of one way.
Here is my questionnaire (somewhat edited for length) between the lines:
-------------------------------------------------------------------------------
[lightblue]Do you wish to fill out the questionnaire [[Y,n]? [green menu]yn|
[choice]n[quit]
[open]D:\Max\Quest.Tmp
[post][lightblue]
Enter your first and last name: [green ansreq clear_stacked readln]
[lightblue]
Enter your home phone number (including area code): [green readln]
[lightblue]Address (line 1 of 3): [green readln]
[lightblue]Address (line 2 of 3): [green ansopt readln]
[lightblue]Address (line 3 of 3): [green readln]
[lightcyan][ansreq][open]Nul
Thank you for filling out the questionnaire!
When you log off the system will automatically generate a message from
you to the sysop containing your questionnaire answers.
[lightblue enter]
-------------------------------------------------------------------------------
You could run VALMSG from a MECCA, but I like to run it after the user
has logged off. Here is the piece of my Maximus batch file that does
the job:
if not exist quest.tmp goto noquest
valmsg /mper /vquest.tmp /tBob Quinlan
type quest.tmp >>quest.log
del quest.tmp
:noquest
If QUEST.TMP exists VALMSG is run to process it. Then the TYPE command
appends QUEST.TMP onto the end of the permanent QUEST.LOG file and
QUEST.TMP is deleted.
VALMSG returns ERRORLEVEL 0 after a successful run. ERRORLEVEL 1 is
returned to indicate an error.
NOTICE: You may use, copy, and distribute this program freely as long
as you insure that both the executable and the documentation (.DOC)
files are included in the distribution package. The source code does
not need to be included. You may modify this program and document, so
long as reasonable credit is given to the original author if a
substantial portion of the original remains intact. The author is not
responsible for any losses which may occur either directly or indirectly
as a result of using this program.
This program uses the Squish MsgAPI and the Maximus structures written
by Scott J. Dudley. "Squish" is a trademark of Scott J. Dudley.
HISTORY:
Version 1.9 (8/26/92) -- Fixed a problem with handling multiple-word
parameters.
Version 1.8 (8/25/92) -- Added the ability to pass multiple-word
parameters using spaces.
Version 1.7 (8/10/92) -- Provided additional documentation and
examples of how to use the program. No
code changes.
Version 1.6 (6/03/92) -- Added *.MSG support. /M is now the "number"
for the area, not its path. You may need to
use the /A switch if AREA.DAT is not in the
current directory.
Version 1.5 (5/26/92) -- Use _fsopen instead of local s_fopen.
Version 1.4 (5/13/92) -- Added file sharing.
Version 1.3 (4/23/92) -- Zero-out headers. Cleaned up docs.
Version 1.2 (4/18/92) -- Extract username properly from data.
Version 1.1 (4/17/92) -- Added switches.
Version 1.0 (4/15/92) -- Original release. Written in Borland C.
Large memory model
*/
#include <ctype.h>
#include <dos.h>
#include <errno.h>
#include <fcntl.h>
#include <io.h>
#include <share.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys\stat.h>
#include <sys\types.h>
#include <msgapi.h> /* From MsgAPI by Scott J. Dudley */
#include <prog.h> /* From MsgAPI by Scott J. Dudley */
#include <alc.h> /* From MsgAPI by Scott J. Dudley */
#include <mstruct1.h> /* Maximus structures by Scott J. Dudley: modified
to avoid duplicate definitions of datestamps */
#define MAXLINE (128)
#define MAXNAME (36)
#define BUFSIZE (2048)
int main(int argc, char *argv[])
{
struct _area arearef;
XMSG xmsg;
MSG *area;
MSGH *msg;
UMSGID uid;
char ctrl[MAXLINE];
char buffer[BUFSIZE];
long textlen;
dword offset, msgn;
int t;
int ctrllen;
struct _minf mi;
long slen;
char areaname[MAX_ALEN] = {""};
char areafile[MAXLINE] = {"AREA.DAT"};
FILE *areafile_fp;
char valfile[MAXLINE] = {""};
FILE *valfile_fp;
char msgpath[MAXLINE];
FILE *msgpath_fp;
struct date sysdate;
struct time systime;
char param = '\0';
char line[MAXLINE];
char *ch;
int i;
/************/
/* VALMSG */
/************/
printf("VALMSG 1.9 -- Copyright 1992 by Bob Quinlan (8/26/92)\n");
/* Zero-out header */
memset(&xmsg, 0, sizeof(XMSG));
/* Process switches */
*xmsg.from = '\0';
*xmsg.subj = '\0';
*xmsg.to = '\0';
for (i=1; i<argc; i++)
{
/* Convert previous param to uppercase so single-pass switches will
not recognize it more than once */
param = toupper(param);
/* If new parameter set it to lower case for first pass */
if (argv[i][0] == '/')
param = tolower(argv[i][1]);
switch (param)
{
case 'a': /* AREA.DAT file */
strncpy(areafile, argv[i]+2, MAXLINE);
break;
case 'F': /* From (sendar): append additional words */
strncat(xmsg.from, " ", XMSG_FROM_SIZE);
/* Fall through to next case! */
case 'f': /* From (sender): defaults to sender's name */
strncpy(xmsg.from, argv[i]+((islower(param) != 0)*2),
XMSG_FROM_SIZE);
/* Replace underscores with spaces */
while ((ch = strchr(xmsg.from, '_')) != NULL)
*ch = ' ';
break;
case 'm': /* Message area "number" */
if (strlen(argv[i]+2) < MAX_ALEN)
strcpy(areaname, argv[i]+2);
else
{
fprintf(stderr,
"VALMSG: %s is too long to be an area \"number\"\n",
argv[i]+2);
exit(1);
}
break;
case 'S': /* Subject: append additional words */
strncat(xmsg.subj, " ", XMSG_SUBJ_SIZE);
/* Fall through to next case! */
case 's': /* Subject: defaults to "Questionnaire" */
strncpy(xmsg.subj, argv[i]+((islower(param) != 0)*2), XMSG_SUBJ_SIZE);
/* Replace underscores with spaces */
while ((ch = strchr(xmsg.subj, '_')) != NULL)
*ch = ' ';
break;
case 'T': /* To (receiver): append additional words */
strncat(xmsg.to, " ", XMSG_TO_SIZE);
/* Fall through to next case! */
case 't': /* To (receiver): defaults to "Sysop" */
strncat(xmsg.to, argv[i]+((islower(param) != 0)*2), XMSG_TO_SIZE);
/* Replace underscores with spaces */
while ((ch = strchr(xmsg.to, '_')) != NULL)
*ch = ' ';
break;
case 'v': /* Validation file */
strncpy(valfile, argv[i]+2, MAXLINE);
break;
default:
fprintf(stderr, "VALMSG: Unknown switch: %s\n", argv[i]);
break;
}
}
if ((*valfile == '\0') || (*areaname == '\0'))
{
fprintf(stderr, "VALMSG: Must define /m and /v.\n");
exit(1);
}
/* Open the area file */
if ((areafile_fp = _fsopen(areafile, "rb", SH_DENYNO)) == NULL)
{
fprintf(stderr, "VALMSG: Unable to open area file: %s\n", areafile);
exit(1);
}
/* Read message area data from the area file */
fread(&arearef, sizeof(struct _area), 1, areafile_fp);
slen = arearef.struct_len;
*msgpath = '\0';
i = 0;
do
{
if (strcmpi(arearef.name, areaname) == 0)
{
strcpy(msgpath, arearef.msgpath);
break;
}
fseek(areafile_fp, (++i)*slen, SEEK_SET);
} while (fread(&arearef, sizeof(struct _area), 1, areafile_fp) > 0);
/* Close the area file */
fclose(areafile_fp);
/* If no message path was assigned... */
if (*msgpath == '\0')
{
fprintf(stderr, "VALMSG: %s is not a valid message area\n", areaname);
exit(1);
}
/* Read validation data */
if ((valfile_fp = _fsopen(valfile, "rb", SH_DENYNO)) == NULL)
{
fprintf(stderr, "VALMSG: Unable to open validation file: %s\n", valfile);
exit(1);
}
textlen = fread(&buffer, sizeof(char), BUFSIZE, valfile_fp);
fclose(valfile_fp);
/* Fill in the message header fields */
if (*xmsg.from == '\0')
{
/* Extract user's name from validation data */
strncpy(xmsg.from, buffer+2, MAXNAME);
ch = strchr(xmsg.from, '\t');
if (ch != NULL)
*ch = '\0';
}
if (*xmsg.to == '\0')
strcpy(xmsg.to, "Sysop");
if (*xmsg.subj == '\0')
strcpy(xmsg.subj, "Questionnaire");
strcpy(ctrl, "\x1");
ctrllen = strlen(ctrl);
xmsg.attr = MSGPRIVATE;
getdate(&sysdate);
gettime(&systime);
xmsg.date_written.date.yr = sysdate.da_year-1980; /* Note: date.yr = year-1980 */
xmsg.date_written.date.mo = sysdate.da_mon;
xmsg.date_written.date.da = sysdate.da_day;
xmsg.date_written.time.hh = systime.ti_hour;
xmsg.date_written.time.mm = systime.ti_min;
xmsg.date_written.time.ss = systime.ti_sec;
xmsg.date_arrived = xmsg.date_written;
/* Open the message API */
t = arearef.type;
mi.def_zone = 1;
MsgOpenApi(&mi);
/* Open the message area */
if ((area=MsgOpenArea(msgpath, MSGAREA_CRIFNEC, t)) == NULL)
{
fprintf(stderr, "VALMSG: Unable to open %s!\n", msgpath);
exit(1);
}
/* Write the user message */
MsgLock(area);
if ((msg=MsgOpenMsg(area, MOPEN_CREATE, 0L)) == NULL)
{
fprintf(stderr, "VALMSG: Unable to write to ouptut area. msg#%ld\n", msgn);
exit(1);
}
MsgWriteMsg(msg, FALSE, &xmsg, buffer, textlen, textlen, ctrllen, ctrl);
MsgCloseMsg(msg);
MsgUnlock(area);
/* Close the message area */
MsgCloseArea(area);
/* Close the message API */
MsgCloseApi();
return 0;
}